﻿/* =========================================================================
 * Project:       CCP_PWM Mode_Half Bridge
 * File:          main.c
 * Description:   
; set pwm mode Half-bridge by CCPCON

; half-bridge: P1A active High. P1B active Low.

; P1A(PB2), P1B(PA5)
; Duty = pwm_value / timer_value;
; Frequency = 4M/4T/timer_value;
; deand band = 1 CPU cycle
; When INTF3 bit5(T5IF/CCPIF) occur, PB0 is toggle output

; PWM duty = 0x200/0x3FF = 50%
; timer_value = 0x3FF 	
; pwm_value = 0x200

; Author:  		 David Wei      
; Version:       V1.0 
; Date:          2021/05/07
 =========================================================================*/
#include <ny8.h>
#include "ny8_constant.h"
#include "color.h"

#define UPDATE_REG(x)	__asm__("MOVR _" #x ",F")

#define IR_INIT 0
#define IR_high_1ms2 1
#define IR_high_400us 2
#define IR_NEXT 3
#define IR_STOP 4

unsigned char time = 0;
unsigned int count = 0;
unsigned char ioState;
unsigned char ioFlag = 0;
unsigned int tmp = 0;
unsigned char IRState = IR_INIT;
unsigned char bitCount = 0;
unsigned char IrData1 = 0;
unsigned char IrData2 = 0;
unsigned char IrData3 = 0;
unsigned char IrData0 = 0;
unsigned char IrDataFlag = 0;

unsigned char div=0;

unsigned char oldBrightness = 10;
extern unsigned char savedMode;
extern unsigned char savedRed;
extern unsigned char savedGreen;
extern unsigned char savedBlue;
extern unsigned char savedRgbBrightness;
extern unsigned char savedWarm;
extern unsigned char savedCold;
extern unsigned char savedTempBrightness;
extern unsigned int stepCnt;
extern unsigned char powerState;
extern unsigned char savedSpeed;
extern unsigned int speedStep;
extern unsigned int speedStepValue[];
extern unsigned int stepCntSaved;
extern unsigned char nightModeFlag;
extern unsigned int saved10SecondCnt;
extern unsigned int countDownCount;
extern unsigned char autoOffModeFlag;

extern unsigned char personalSavedMode;
extern unsigned char personalSavedRed;
extern unsigned char personalSavedGreen;
extern unsigned char personalSavedBlue;
extern unsigned char personalSavedWarm;
extern unsigned char personalSavedCold;
extern unsigned char personalSavedBrightness;
extern unsigned char colorUpdate;

void isr(void) __interrupt(0)
{	
	if(INTFbits.T0IF)
	{	
		//TMR0 = 0x3E;
		INTFbits.T0IF = 0;
		//INTF = (unsigned char)~(C_INT_TMR0);	// Clear T0IF flag bit	
		if(IrDataFlag == 1)
		{
			ioFlag = 1;
			time = 0xFF;
			IrDataFlag = 0;
		}
		//PCON1 &= ~C_TMR0_En;
		
	}
	/*
	if(INTE2bits.T4IF)
	{
		//INTE2 = (unsigned char)~(C_INF_TMR4);
		INTE2bits.T4IF = 0;
		stepCnt++;
	}
	*/
	if(INTFbits.T1IF)
	{
		//INTE2 = (unsigned char)~(C_INF_TMR4);
		INTFbits.T1IF = 0;
		div++;
		if (div >= 8)
		{
			div = 0;
			stepCnt++;
		}
	}
	
	if(INTFbits.PABIF)
	{
	    INTFbits.PABIF = 0;
		//INTF = (unsigned char)~(C_INT_PABKey);	// Clear INTIF(External interrupt flag bit)	
					// Enable Timer0
		if(PORTAbits.PA5) 
		{
			ioState = 1;
		}
		else 
		{	
			ioState = 0;
		}
		if (IrDataFlag == 0)
		{
			TMR0 = 0;
			IrDataFlag = 1;
		}
		else
		{
			//PCON1 &= ~C_TMR0_En;
			
			time = TMR0;
			TMR0 = 0;			
			ioFlag = 1;
		}
	}
}

void initDev(void)
{
	IOSTA |=  C_PA5_Input;	
	AWUCONbits.WUPA5 = 1;
	PCONbits.PHPA5 = 0;
	TMR0 = 0;								// Load 0x00 to TMR0 (Initial Timer0 register)
	T0MD = C_PS0_TMR0 | C_PS0_Div256 ;		// Prescaler0 is assigned to Timer0, Prescaler0 dividing rate = 1:8,clock source is instruction clock
	PCON1 |= C_TMR0_En;
}

unsigned char decodeIR(void)
{
	unsigned char n = 0;
	//time = 0x3FF - time;
	if (time > 220) 
	{
		bitCount = 0;
		IRState = IR_INIT;
		return 0;
	}
	switch (IRState)
	{
		case IR_INIT:
			bitCount = 0;
			IrData0 = 0;
			IrData1 = 0;
			IrData2 = 0;
			IrData3 = 0;
			//PORTAbits.PA5 = ~PORTAbits.PA5;
			if(ioState == 0)
			{
				if(time > 19 && time < 29)
				{
					IRState = IR_high_1ms2;
				}
				else if(time > 5 && time < 11)
				{
					IRState = IR_high_400us;
				}
			}
			break;	
		case IR_high_1ms2:
			if(ioState == 1 && time > 5 && time < 11)
			{
				n = bitCount/8;
				if(n==0)
			    {
			    	IrData0 = IrData0 << 1;
			    	IrData0 = IrData0 | 0x01;
			    }
			    else if(n==1)
			    {
			    	IrData1 = IrData1 << 1;
			    	IrData1 = IrData1 | 0x01;
			    }
			    else if(n==2)
			    {
			    	IrData2 = IrData2 << 1;
			    	IrData2 = IrData2 | 0x01;
			    }
			    bitCount++;
			    IRState = IR_NEXT;
			}
			else
			{
				IRState = IR_INIT;
			}
			break;
		case IR_high_400us:
			if(ioState == 1 && time > 19 && time < 29)
			{
				n = bitCount/8;
				if(n==0)
			    {
			    	IrData0 = IrData0 << 1;
			    }
			    else if(n==1)
			    {
			    	IrData1 = IrData1 << 1;
			    }
			    else if(n==2)
			    {
			    	IrData2 = IrData2 << 1;
			    }
			    bitCount++;
			    IRState = IR_NEXT;
			}
			else
			{
				IRState = IR_INIT;
			}
			break;
		case IR_NEXT:
			if(ioState == 0)
			{
				if(time > 19 && time < 29)
				{
					IRState = IR_high_1ms2;
				}
				else if(time > 5 && time < 11)
				{
					IRState = IR_high_400us;
				}
				if(bitCount > 23) 
				{
					if(IRState == IR_high_400us) 
					{
						IRState = IR_STOP;
						return IrData2;
					}
					else IRState = IR_INIT;
				}
			}
			break;
		case IR_STOP:
			IRState = IR_INIT;
			break;
	}
	return 0;
}

void IrHandler(void)
{
	static unsigned char repeatCount = 0;
	static unsigned int irCnt;
	static unsigned char repeatCMD = 0;
	static unsigned char irFlag = 0;
	unsigned char t = 0;
	unsigned char holdFlag = 0;
	if(ioFlag) 
   	{
   		ioFlag = 0;
   		t = decodeIR();
   		if(irFlag)
   		{
   			if(t == repeatCMD)
   			{
   				//PORTAbits.PA2 = ~PORTAbits.PA2;
   				repeatCount++;
   				if(repeatCount > 200) repeatCount = 200;
   				irCnt = stepCnt;
   			}
   			t = 0;
   		}
   		else
   		{
   			if(t > 0)
   			{
   				
   				irFlag = 1;
   				repeatCount = 1;
   				repeatCMD = t;
   				irCnt = stepCnt;
   				t = 0;
   			}
   			t = 0;
   		}	
   	}
   	
   	if(irFlag)
   	{
   		//PORTAbits.PA4 = ~PORTAbits.PA4;
   		if(irCnt + 15 == stepCnt)
   		{
   			if(repeatCount > 50) holdFlag = 1;
   			repeatCount = 0;
   			t = repeatCMD;
   			irFlag = 0;
   		}
   	}
   	
   	if(holdFlag)
   	{
   		//PORTBbits.PB1 = ~PORTBbits.PB1;
   		//if(t == 0x46)
   		if (powerState != 0)
   		{
	   		if(t == 0x02)
	   		{
	   			autoOffModeFlag = 0;
	   		}
	   		//else if(t == 0x0D)
	   		//else if(t == 0x52)
	   		else if(t == 0x14)
	   		{
	   			if(savedMode < COLOR_MODE_FLASH)
	   			{
		   			personalSavedMode = savedMode;  
		   			eeprom_protect_unlock(); 			// unlock write-protection
					//eeprom_write (SAVE_PERSONAL_MODE, personalSavedMode);
					eeprom_write_timeout (SAVE_PERSONAL_MODE, personalSavedMode, 5);
		   			if(personalSavedMode == COLOR_MODE_COLORTEMP) 
		   			{
		   				personalSavedBrightness =  savedTempBrightness;
		   				personalSavedCold = savedCold;
		   				eeprom_protect_unlock(); 			// unlock write-protection
						//eeprom_write (SAVE_PERSONAL_COLOR_TEMP_COLD, personalSavedCold);
						eeprom_write_timeout (SAVE_PERSONAL_COLOR_TEMP_COLD, personalSavedCold, 5);
		   				personalSavedWarm = savedWarm;
		   				eeprom_protect_unlock(); 			// unlock write-protection
						//eeprom_write (SAVE_PERSONAL_COLOR_TEMP_WARM, personalSavedWarm);
						eeprom_write_timeout (SAVE_PERSONAL_COLOR_TEMP_WARM, personalSavedWarm, 5);
		   			}
		   			else 
		   			{
		   				personalSavedBrightness = savedRgbBrightness;
		   				personalSavedRed = savedRed;
		   				eeprom_protect_unlock(); 			// unlock write-protection
						//eeprom_write (SAVE_PERSONAL_COLOR_RGB_RED, personalSavedRed);
						eeprom_write_timeout (SAVE_PERSONAL_COLOR_RGB_RED, personalSavedRed, 5);
		   				personalSavedGreen = savedGreen;
		   				eeprom_protect_unlock(); 			// unlock write-protection
						//eeprom_write (SAVE_PERSONAL_COLOR_RGB_GREEN, personalSavedGreen);
						eeprom_write_timeout (SAVE_PERSONAL_COLOR_RGB_GREEN, personalSavedGreen, 5);
		   				personalSavedBlue = savedBlue;
		   				eeprom_protect_unlock(); 			// unlock write-protection
						//eeprom_write (SAVE_PERSONAL_COLOR_RGB_BLUE, personalSavedBlue);
						eeprom_write_timeout (SAVE_PERSONAL_COLOR_RGB_BLUE, personalSavedBlue, 5);
		   			}
		   			eeprom_protect_unlock(); 			// unlock write-protection
					//eeprom_write (SAVE_PERSONAL_COLOR_BRIGHTNESS, personalSavedBrightness);
					eeprom_write_timeout (SAVE_PERSONAL_COLOR_BRIGHTNESS, personalSavedBrightness, 5);
	   			}
	   		}
	   	}
   	}
   	else
   	{
		if (t != 0)
   		{
   			//if (nightModeFlag) nightModeFlag = 0;
   			if (powerState == 0)
   			{
   				//if(t == 0x45)
   				if(t == 0x01)
   				{
   					powerState = 1;
   					colorUpdate = 1;
   				}
   			}
   			else
   			{
   				nightModeFlag = 0;
	   			//if (t == 0x40)
	   			if(t == 0x05)
	   			{
	   				if (savedMode == COLOR_MODE_COLORTEMP)
	   				{
	   					savedTempBrightness =  savedTempBrightness > 2 ? savedTempBrightness - 1 : 1;
	   				}
	   				else if (savedMode == COLOR_MODE_SMOTH || savedMode == COLOR_MODE_FLASH)
	   				{  					
	   					savedSpeed =  savedSpeed < 10 ? savedSpeed + 1 : 10;
	   					//speedStep = (unsigned int)(speedStepValue + (savedSpeed - 1));
	   					//speedStep = 406 << savedSpeed;
	   					stepCntSaved = stepCnt;
	   					
	   				}
	   				else if(savedMode == COLOR_MODE_COLORRGB)
	   				{
	   					savedRgbBrightness =  savedRgbBrightness > 2 ? savedRgbBrightness - 1 : 1;
	   				}
	   			}
	   			//else if (t == 0x44)
	   			else if (t == 0x04)
	   			{
	   				if (savedMode == COLOR_MODE_COLORTEMP)
	   				{
	   					savedTempBrightness =  savedTempBrightness < 10 ? savedTempBrightness + 1 : 10;
	   				}
	   				else if (savedMode == COLOR_MODE_SMOTH || savedMode == COLOR_MODE_FLASH)
	   				{
	   					savedSpeed = savedSpeed > 2 ? savedSpeed - 1 : 1;
	   					//speedStep = (unsigned int)(speedStepValue+(savedSpeed - 1));
	   					//speedStep = 406 << savedSpeed;
	   					stepCntSaved = stepCnt;
	   					
	   				}
	   				else if(savedMode == COLOR_MODE_COLORRGB)
	   				{
	   					savedRgbBrightness =  savedRgbBrightness < 10 ? savedRgbBrightness + 1 : 10;
	   				}
	   			}
	   			//else if(t == 0x52)
	   			//else if(t == 0x16)
	   			else if (t == 0x0A)
	   			{
	   				if (savedMode == COLOR_MODE_COLORTEMP)
	   				{
	   					savedWarm = savedWarm > 0 ? savedWarm - 1 : 0;
	   					savedCold = 10 - savedWarm;
	   				}
	   				else if (savedMode == COLOR_MODE_COLORRGB)
	   				{
	   					if (savedBlue == 0)
	   					{
	   						if (savedRed == 0)
	   						{
	   							savedBlue = 1;
	   							savedGreen = 9;
	   						}
	   						else 
	   						{
	   							savedRed--;
	   							savedGreen = 10 - savedRed;
	   						}
	   					}
	   					else if (savedRed == 0)
	   					{
	   						if (savedGreen == 0)
	   						{
	   							savedBlue = 9;
	   							savedRed = 1;
	   						}
	   						else 
	   						{
	   							savedGreen--;
	   							savedBlue = 10 - savedGreen;
	   						}
	   					}
	   					else if (savedGreen == 0)
	   					{
	   						if (savedBlue == 0)
	   						{
	   							savedRed = 9;
	   							savedGreen = 1;
	   						}
	   						else
	   						{
	   							savedBlue--;
	   							savedRed = 10 - savedBlue;
	   						}
	   					}
	   				}
	   				
	   			}
	   			//else if(t == 0x4A)
	   			//else if(t == 0x19)
	   			else if (t == 0x0B)
	   			{
	   				if (savedMode == COLOR_MODE_COLORTEMP)
	   				{
	   					savedWarm = savedWarm < 10 ? savedWarm + 1 : 10;
	   					savedCold = 10 - savedWarm;
	   				}
	   				else if (savedMode == COLOR_MODE_COLORRGB)
	   				{
	   					if (savedBlue == 0)
	   					{
	   						if (savedGreen == 0)
	   						{
	   							savedBlue = 1;
	   							savedRed = 9;
	   						}
	   						else 
	   						{
	   							savedGreen--;
	   							savedRed = 10 - savedGreen;
	   						}
	   					}
	   					else if (savedRed == 0)
	   					{
	   						if (savedBlue == 0)
	   						{
	   							savedGreen = 9;
	   							savedRed = 1;
	   						}
	   						else 
	   						{
	   							savedBlue--;
	   							savedGreen = 10 - savedBlue;
	   						}
	   					}
	   					else if (savedGreen == 0)
	   					{
	   						if (savedRed == 0)
	   						{
	   							savedBlue = 9;
	   							savedGreen = 1;
	   						}
	   						else
	   						{
	   							savedRed--;
	   							savedBlue = 10 - savedRed;
	   						}
	   					}
	   				}
	   			}
	   			/*
	   			else if(t == 0x45)
	   			{
	   				powerState = 1;
	   			}*/
	   			//else if(t == 0x46)
	   			else if (t == 0x02)
	   			{
	   				powerState = 0;
	   				autoOffModeFlag = 0;
	   			}
	   			/*
	   			else if(t == 0x19)
	   			{
	   				writeColor();
	   			}*/
	   			//else if(t == 0x0C)
	   			else if(t == 0x0D)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 10;
	   				savedGreen = 0;
	   				savedBlue = 0;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x18)
	   			else if(t == 0x0E)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 0;
	   				savedGreen = 10;
	   				savedBlue = 0;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x5E)
	   			else if(t == 0x0F)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 0;
	   				savedGreen = 0;
	   				savedBlue = 10;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x42)
	   			else if(t == 0x13)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 7;
	   				savedGreen = 3;
	   				savedBlue = 0;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x1C)
	   			else if(t == 0x11)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 3;
	   				savedGreen = 7;
	   				savedBlue = 0;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x08)
	   			else if(t == 0x10)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 8;
	   				savedGreen = 2;
	   				savedBlue = 0;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x5A)
	   			else if(t == 0x12)
	   			{
	   				savedMode = COLOR_MODE_COLORRGB;
	   				savedRed = 5;
	   				savedGreen = 0;
	   				savedBlue = 5;
	   				//savedRgbBrightness = 10;
	   			}
	   			//else if(t == 0x16)
	   			//else if(t == 0x15)
	   			else if(t == 0x08)
	   			{
	   				savedMode = COLOR_MODE_SMOTH;
	   			}
	   			//else if(t == 0x07)
	   			else if(t == 0x07)
	   			{
	   				savedMode = COLOR_MODE_FLASH;
	   			}
	   			//else if(t == 0x15)
	   			//else if(t == 0x43)
	   			else if(t == 0x06)
	   			{
	   				savedMode = COLOR_MODE_COLORTEMP;
	   				savedWarm = 9;
	   				savedCold = 10 - savedWarm;
	   				//savedTempBrightness = 10;
	   			}
	   			else if(t == 0x09)

	   			{
	   				savedMode = COLOR_MODE_COLORTEMP;
	   				savedWarm = 6;
	   				savedCold = 10 - savedWarm;
	   				//savedTempBrightness = 10;
	   			}
	   			//else if(t == 0x19)
	   			else if(t == 0x0C)
	   			{
	   				savedMode = COLOR_MODE_COLORTEMP;
	   				savedWarm = 3;
	   				savedCold = 10 - savedWarm;
	   				//savedTempBrightness = 10;
	   			}
	   			else if(t == 0x03)
	   			{
	   				savedMode = COLOR_MODE_COLORTEMP;
	   				nightModeFlag = 1;
	   				saved10SecondCnt = stepCnt;
	   				countDownCount = 90;  //900s 倒计时
	   				savedWarm = 10;
	   				savedCold = 10 - savedWarm;
	   				savedTempBrightness = 1;
	   			}
	   			//else if(t == 0x43)
	   			else if(t == 0x15)
	   			{
	   				saved10SecondCnt = stepCnt;
	   				if (autoOffModeFlag == 1)
	   				{
	   					countDownCount += 360;
	   					if (countDownCount > 8640)
	   					{
	   						countDownCount -= 8640;
	   					}
	   				}
	   				else
	   				{
	   					autoOffModeFlag = 1;
	   					countDownCount = 360;  //3600s 倒计时
	   				}
	   			}
	   			//else if(t == 0x0D)
	   			else if(t == 0x14)
	   			{
	   				savedMode = personalSavedMode;
	   				savedCold = personalSavedCold;
	   				savedWarm = personalSavedWarm;
	   				savedRed = personalSavedRed;
	   				savedGreen = personalSavedGreen;
	   				savedBlue = personalSavedBlue;
	   				savedTempBrightness = savedRgbBrightness = personalSavedBrightness;
	   			}
	   		}
   			updateColor();
   			writeColor();
   		}
   	}
}

void main(void)
{
	
    DISI();
    
    initColor();
    initDev();
    //INTE = C_INT_TMR0;
    INTE = C_INT_TMR1 | C_INT_TMR0 | C_INT_PABKey; 	
    ENI();
    
    while(1)
    {
        colorHandler();
    	//if(ioFlag) 
    	{
    		IrHandler();
    		
    		//updateColor();
    		//unsigned char t;
    		//t = decodeIR();
    		//PORTBbits.PB2 ^= 1;
    		//ioFlag = 0;
    		//if(t != 0) PORTBbits.PB2 ^= 1;
    	}
        CLRWDT();							// Clear WatchDog
    }
}
